/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package network;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import utils.StringUtils;
import utils.Utils;

/**
 *
 * @author Kvest
 */
public class PacketBuilder 
{
    public static final String TO_DISPETCHER = "Dispatcher";
    public static final String POINT_TO_POINT = "PointToPoint";  
    public static final String REASON_REFUSE = "RefuseOrder";
    public static final String DEFAULT_CONNECTION_TYPE = "PointToGroup";
    public static final int DEFAULT_DESTINATION_ID = 2;
    
    public static final String DEVICE_SOFTWARE_VERSION = "5.0.0.0";
    
    public static byte[] createLogin(int GroupID,String loginName,String password,boolean IsUniqConnection)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.SrvLogin", true);

            //GroupID
            stream.writeInt16(GroupID);
            //login
            stream.write(loginName);
            //password
            stream.write(password);
            //IsUniqConnection
            stream.write(IsUniqConnection);
            //PacketNumber
            stream.writeInt32(-1);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createLogout(int srvID,byte[] guid)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.SrvLogOut", true);
            
            //srvID
            stream.writeInt32(srvID);
            //guid
            stream.write(guid);
            //PacketNumber
            stream.writeInt32(-1);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createPingAnswer()
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.SrvPingAnswer", true);

            //PacketNumber
            stream.writeInt32(-1);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createSrvTransfereData(String connectionType,int srvID,int destinationID,byte[] guid,boolean log,byte[] body)
    {
        return createSrvTransfereData(connectionType, srvID, destinationID, guid, log, body, -1);
    }
    
    public static byte[] createSrvTransfereData(String connectionType,int srvID,int destinationID,byte[] guid,boolean log,byte[] body, int packetNumber)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.SrvTransfereData", true);
            
            //connectionType
            stream.write(connectionType);
            //srvID
            stream.writeInt32(srvID);
            //destinationID
            stream.writeInt32(destinationID);
            //guid
            stream.write(guid);
            //log
            stream.write(log);
            //body
            stream.write(body);
            //PacketNumber
            stream.writeInt32(packetNumber);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createIMapMessage(String destination,String callSign,String message, int peopleID)
    {        
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.IMapMessage", false);
           
            //Destination
            stream.write(destination);
            //CallSign
            stream.write(callSign);
            //Message
            stream.write(message);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyRegisterOnRelay(String nick,boolean fromDriver,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PPCRegisterOnRelay", false);
            //nick
            stream.write(nick);
            //fromDriver
            stream.write(fromDriver);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyCarOnAddressRequest(int orderId, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.CarOnAddressRequest", false);
            //orderId
            stream.writeInt32(orderId);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyRegisterOnTaxiParking(int parkingID,String nick,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.RegisterOnTaxiParking", false);
            //parkingID
            stream.writeInt32(parkingID);
            //nick
            stream.write(nick);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createReqPreOrders(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetPrelimOrders"/*"IMAP.Net.GetPreliminaryOrders"*/, false);

            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyPPSOrderCancelRequest(int orderID,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PPSOrderCancelRequest", false);
            //orderID
            stream.writeInt32(orderID);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createFilteredTaxiPаrkings(String[] regions, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.FilteredTaxiPаrkings", false);
            //Размер массива
            stream.writeInt32(regions.length);
            //Массив
            for (int i = 0; i < regions.length; ++i)
            {
                stream.write(regions[i]);
            }
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyOrderCancel(int orderID, String reason, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.OrderCancel", false);
            //orderID
            stream.writeInt32(orderID);
            //reason
            stream.write(reason);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createBodyPickingUpCharge(int orderID, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PickingUpCharge", false);
            //orderID
            stream.writeInt32(orderID);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
        
    public static byte[] createBodyCW_ConnectDriverClient(int orderID, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.CW_ConnectDriverClient", false);
            //orderID
            stream.writeInt32(orderID);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }   
    }

    public static byte[] createBodyOrderAnswer(int orderID,String reason,String addition,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.OrderAnswer", false);
            //orderID
            stream.writeInt32(orderID);
            //reason
            stream.write(reason);
            //addition
            stream.write(addition);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createGetWorkReport(long from,long to,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetWorkReport", false);
            //from
            stream.write(from);
            //to
            stream.write(to);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createBodyGetDriverParkingPosition(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetDriverParkingPosition", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }	
    }
	
    public static byte[] createDangerWarning(int geoX, int geoY, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.DangerWarning",  false);
        
            //GeoX
            stream.writeInt32(geoX);
            
            //GeoY
            stream.writeInt32(geoY);
            
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }	    
    }
    
    public static byte[] createMoveBackInQueue(int countPositions, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.MoveBackInQueue",  false);
            
            //CountPositions;
            stream.writeInt32(countPositions);
        
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }	    
    }
    
    public static byte[] createVersionDeviceSoftware(String deviceType, String versionDevice, int peopleID) {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.VersionDeviceSoftware", false);
            
            //deviceType
            stream.write(deviceType);
            //versionDevice
            stream.write(versionDevice);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyGetPPCSettingsXML(int peopleID) {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetPPCSettingsXML", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
    
    public static byte[] createBodyGetPPCSettings(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetPPCSettings", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }	
    }
	
    public static byte[] createBodyGetTaxiParkings(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetTaxiParkings", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createBodyUpdateJavaConnectionState(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.UpdateJavaConnectionState", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createBodyGetTaxiParkingsLastChangeDate(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetTaxiParkingsLastChangeDate", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }	
    }
	
    public static byte[] createGetBalanceData(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetCSBalance", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
        
    public static byte[] createUnRegisterOnTaxiParking(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.UnRegisterOnTaxiParking", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }   
    }
	
    public static byte[] createGetTaxiParkingStatistic(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetTaxiParkingStatistic", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createTrackContinue(int orderID,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.TrackContinue", false);
            //orderID
            stream.writeInt32(orderID);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }   
    }
	
    public static byte[] createDriverWaiting(int orderID,int delay,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.DriverWaiting", false);
            //orderID
            stream.writeInt32(orderID);
            //delay
            stream.writeInt32(delay);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createSignPreliminaryOrder(int orderID,String callSign, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.SignPreliminaryOrder", false);
            //orderID
            stream.writeInt32(orderID);
            //callSign
            stream.write(callSign);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createFeedTime(int orderID, int time, int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PPSOrderDriverTimeUpdate", false);
            //orderID
            stream.writeInt32(orderID);
            //time
            stream.writeInt32(time);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }  
    }

    public static byte[] createDriverDelay(int orderID,int delay,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.DriverDelay", false);
            //orderID
            stream.writeInt32(orderID);
            //delay
            stream.writeInt32(delay);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        } 
    }

    public static byte[] createGetOrdersOfDriver(String filter, int peopleID) {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetOrdersOfDriver", false);
            //WhereStatement
            stream.write(filter);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }   
    }
    
    public static byte[] createGetOrders(String filter)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.GetOrders", false);
            //WhereStatement
            stream.write(filter);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createSQL(String SQLString)
    {   
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.ExequteQuerryCommand", false);
            //SQLString
            stream.write(SQLString);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }    
    }

    public static byte[] createPassengerOut(int orderID,int delay,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PassengerOut", false);
            //orderID
            stream.writeInt32(orderID);
            //delay
            stream.writeInt32(delay);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }
	
    public static byte[] createDispatcherCall(int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.DispatcherCall", false);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }
    }

    public static byte[] createPPCUnRegisterOnRelay(boolean fromDriver,String type,int peopleID)
    {
        BuilderStream stream = null;
        try
        {
            stream = new BuilderStream("IMAP.Net.PPCUnRegisterOnRelay", false);
            //fromDriver
            stream.write(fromDriver);
            //type
            stream.write(type);
            //peopleID
            stream.writeInt32(peopleID);
            
            return stream.toByteArray();
        }
        catch(IOException ioex)
        {
            return (new byte[]{});
        }
        finally
        {
            try
            {
                stream.close();
            }catch(Exception ex){}
        }   
    }
        
    private static class BuilderStream extends ByteArrayOutputStream
    {
        private static final int PROTOCOL_VERSION = 1;
        
        private boolean addProtocolVersion;
        
        private BuilderStream(String packetName, boolean addProtocolVersion) throws IOException
        {
            super();
            
            this.addProtocolVersion = addProtocolVersion;
            
            //Заглушка для размера пакета
            write((new byte[]{0,0,0,0}));
                    
            //Версия протокола
            if (addProtocolVersion)
            {
                byte[] protocolVersionData = Utils.int32ToByte(PROTOCOL_VERSION);
                write(protocolVersionData);
            }
            
            //Имя пакета
            write(packetName);
        }
        
        public void write(String value) throws IOException
        {
            byte[] valueData = StringUtils.strToBytes(value);
            write(Utils.int32ToByte(valueData.length));
            write(valueData);
        }
        
        public void write(long value) throws IOException
        {
            write(Utils.longToByte(value));
        }
        
        public void writeInt16(int value) throws IOException
        {
            write(Utils.int16ToByte(value));
        }
        
        public void writeInt32(int value) throws IOException
        {
            write(Utils.int32ToByte(value));
        }
        
        public void write(boolean value) throws IOException
        {
            write(Utils.boolToByte(value));
        }
        
        public synchronized byte[] toByteArray()
        {
            byte[] result = super.toByteArray();
            
            //Устанавливаем размер пакета
            byte[] protocolVersionData = Utils.int32ToByte(result.length - 4 - (addProtocolVersion ? 4 : 0)); // 4 + 4 = Размер + версия протокола - их не учитываем в размере пакета
            for (int i = 0; i < 4; ++i)
            {
                result[i] = protocolVersionData[i];
            }
            
            return result;
        }
    }
}
